package dao

import (
	"errors"
	"fmt"
	"strconv"
	"time"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/models/membermodel"
	"yundian/internel/app/models/placemodel"
	"yundian/internel/app/models/room"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	"yundian/internel/pkg/utils"
)

type RoomDao struct {
}

func NewRoomDaoDao() *RoomDao {
	return &RoomDao{}
}

// GetUserRoomWifiList 查询用户WIFI列表
func (dao *RoomDao) GetUserRoomWifiList(param *request.GetUserWifiListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetUserWifiListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)
	dateStr := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
	fields := `r.*,p.place_name, c.all_use_count, d.use_count`
	db := global.Orm.Table("room r").Select(fields)
	db.Joins("LEFT JOIN places p ON r.place_id=p.id")
	db.Joins("LEFT JOIN (SELECT count(1) as all_use_count,place_id,device_sn FROM wifi_ad_orders GROUP BY device_sn) as c ON r.device_sn = c.device_sn")
	db.Joins("LEFT JOIN (SELECT count(1) as use_count,place_id,device_sn FROM wifi_ad_orders WHERE date_str = ? GROUP BY device_sn) as d ON r.device_sn = d.device_sn", dateStr)

	if param.WifiName != "" {
		db.Where("r.wifi_name LIKE ?", fmt.Sprint("%", param.WifiName, "%"))
	} else {
		db.Where("r.wifi_name<>''")
	}

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		userIdArr := NewUserDao().QueryChildUserIds(param.UserId).Unwrap().([]int)
		placesIdArr := NewUserDao().GetPlacesIds(param.UserId, userIdArr).Unwrap().([]int)
		db.Where("r.place_id IN ?", placesIdArr)
	}

	db.Order("r.id DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// GetPlaceMaxRoom 查询门店房间最大值
func (dao *RoomDao) GetPlaceMaxRoom(placeId int) *dingo.ErrorWrap {
	roomName := ``
	db := global.Orm.Table("room r").Select(`IFNULL(MAX(id),'')`)
	db.Where(`place_id=?`, placeId)
	db.Find(&roomName)
	return dingo.ErrorIf(db.Error, roomName)
}

// GetPlaceRoomList 查询门店房间
func (dao *RoomDao) GetPlaceRoomOrderCountBy24(memberId int) *dingo.ErrorWrap {
	var count int64

	db := global.Orm.Table("room_orders ro").Where(`member_id=?`, memberId)
	db.Where(`create_time>DATE_ADD(NOW(), INTERVAL -24 HOUR)`)
	db.Where(`status IN (4,5)`)
	db.Count(&count)

	return dingo.ErrorIf(db.Error, count)
}

// GetPlaceRoomList 查询门店房间
func (dao *RoomDao) GetPlaceRoomList(param *request.AppGetPlaceRoomListReq) *dingo.ErrorWrap {
	var dbList []*request.AppGetPlaceRoomListRes

	fields := `r.id,r.status,r.room,r.type_id,rt.type_name,rt.price,rt.discounts_amount`
	db := global.Orm.Table("room r").Select(fields)
	db.Joins("LEFT JOIN room_type rt ON rt.id=r.type_id")
	db.Where("r.place_id=? AND rt.status=1", param.PlaceId)

	if param.Status > 0 {
		db.Where("r.status=?", param.Status)
	}

	if param.Room != "" {
		db.Where("room LIKE ?", "%"+fmt.Sprintf(`%s`, param.Room)+"%")
	}

	db.Order("room").Find(&dbList)
	return dingo.ErrorIf(db.Error, dbList)
}

// SetBatchDeviceRoom 批量设置设备房间
func (dao *RoomDao) SetBatchDeviceRoom(param *request.SetBatchDeviceRoomReq) *dingo.ErrorWrap {
	var deviceSnList []string
	for _, item := range param.List {
		deviceSnList = append(deviceSnList, item.DeviceSn)
	}

	// 设备绑定校验
	var devicesDbList []*request.GetBatchDeviceRoomDb
	fields := `d.device_sn,d.place_id,p.user_id,count(1)num`
	db := global.Orm.Table("devices d").Select(fields)
	db.Joins(" LEFT JOIN places p ON d.place_id=p.id ")
	db.Where("d.device_sn IN ?", deviceSnList).Group("d.place_id")
	if db.Find(&devicesDbList); len(devicesDbList) != 1 {
		return dingo.ErrorIf(db.Error, devicesDbList, "more")
	}
	tUserId := devicesDbList[0].UserId
	off := tUserId != param.LoginUserId || tUserId == 0 || len(deviceSnList) != devicesDbList[0].Num
	if param.IsAdmin != helper.TypeNumIsAdminOperator && off {
		return dingo.ErrorIf(db.Error, devicesDbList, "devices")
	}

	return dingo.ErrorIf(dao.SetBatchDeviceRoomUpdate(param, devicesDbList[0], deviceSnList).Err, devicesDbList, "")
}

// SetBatchDeviceRoomUpdate 批量设置设备房间
func (dao *RoomDao) SetBatchDeviceRoomUpdate(param *request.SetBatchDeviceRoomReq,
	devicesDb *request.GetBatchDeviceRoomDb, deviceSnList []string) *dingo.ErrorWrap {
	var dbRoomParams []interface{}
	var dbDeviceParams []interface{}
	var updateDeviceSql string

	sql := `INSERT INTO room (place_id,type_id,discounts_amount,status,level,sort,device_sn,room,wifi_name,wifi_password) VALUES`
	for index, item := range param.List {
		targetParams := []interface{}{devicesDb.PlaceId, item.DeviceSn, item.Room, item.WifiName, item.WifiPassword}
		dbRoomParams = append(dbRoomParams, targetParams...)
		sql += `(?,0,0,1,0,0,?,?,?,?)` + utils.AddStrJudge(index == (len(param.List)-1), ",")

		dbDeviceParams = append(dbDeviceParams, []interface{}{item.DeviceSn, item.Room}...)
		updateDeviceSql += ` WHEN device_sn=? THEN ? `
	}
	sql += `ON DUPLICATE KEY UPDATE device_sn=VALUES(device_sn),wifi_name=VALUES(wifi_name),wifi_password=VALUES(wifi_password)`
	if db := global.Orm.Exec(sql, dbRoomParams...); db.Error != nil {
		return dingo.ErrorIf(db.Error)
	}

	updateSql := `UPDATE devices SET room = CASE` + updateDeviceSql + `END WHERE device_sn IN ?`
	db := global.Orm.Exec(updateSql, append(dbDeviceParams, deviceSnList)...)

	return dingo.ErrorIf(db.Error)
}

// GetPlaceRoomDevicesList 门店房间设备列表
func (dao *RoomDao) GetPlaceRoomDevicesList(param *request.GetDeviceRoomListReq) *dingo.ErrorWrap {
	var dbList []*request.GetDeviceRoomListRes
	db := global.Orm.Table("room").Where("place_id=?", param.PlaceId)
	db.Order("device_sn").Order("id DESC").Find(&dbList)

	return dingo.ErrorIf(db.Error, dbList)
}

func (dao *RoomDao) GetRoomList(param *request.GetPlaceRoomListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.GetDeviceRoomListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	db := global.Orm.Table("room")
	if param.PlaceId > 0 {
		db.Where("place_id = ?", param.PlaceId)
	}
	if param.DeviceSn != "" {
		db.Where("device_sn = ?", param.DeviceSn)
	}
	if param.Room != "" {
		db.Where("room = ?", param.Room)
	}
	db.Order("room ASC")
	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// GetPlaceRoomDevicesList 门店房间设备列表
func (dao *RoomDao) GetPlaceRoomDevicesListByPlaceId(placeId int) *dingo.ErrorWrap {
	var dbList []*room.RoomListByPlaceId
	db := global.Orm.Table("room").Where("place_id = ?", placeId)
	db.Order("id DESC").Find(&dbList)

	return dingo.ErrorIf(db.Error, dbList)
}

// PlaceRoomDevicesUpdate 更新房间设备
func (dao *RoomDao) PlaceRoomDevicesUpdate(param *request.BindDeviceAndRoomReq) *dingo.ErrorWrap {
	db := global.Orm.Table("room").Where("place_id=? AND room=?", param.PlaceId, param.Room)
	db.Update("device_sn", param.DeviceSn)

	return dingo.ErrorIf(db.Error)
}

// SetBatchPlaceRoomUpdate 批量设置设备房间
func (dao *RoomDao) SetBatchPlaceRoomUpdate(param *request.SetBatchDeviceRoomReq) *dingo.ErrorWrap {
	var dbRoomParams []interface{}
	var dbDeviceParams []interface{}
	var updateDeviceSql string

	sql := `INSERT INTO room (place_id,type_id,discounts_amount,status,level,sort,device_sn,room,wifi_name,wifi_password) VALUES`
	for index, item := range param.List {
		targetParams := []interface{}{param.PlaceId, item.DeviceSn, item.Room, item.WifiName, item.WifiPassword}
		dbRoomParams = append(dbRoomParams, targetParams...)
		sql += `(?,0,0,1,0,0,?,?,?,?)` + utils.AddStrJudge(index == (len(param.List)-1), ",")

		dbDeviceParams = append(dbDeviceParams, []interface{}{item.DeviceSn, item.Room}...)
		updateDeviceSql += ` WHEN device_sn=? THEN ? `
	}
	sql += `ON DUPLICATE KEY UPDATE wifi_name=VALUES(wifi_name),wifi_password=VALUES(wifi_password)`
	if db := global.Orm.Exec(sql, dbRoomParams...); db.Error != nil {
		return dingo.ErrorIf(db.Error)
	}

	//updateSql := `UPDATE devices SET room = CASE` + updateDeviceSql + `END WHERE place=?`
	//db := global.Orm.Exec(updateSql, append(dbDeviceParams, param.PlaceId)...)
	//return dingo.ErrorIf(db.Error)
	return dingo.ErrorIf(nil)
}

// 查询可提现续住订单
func (dao *RoomDao) GetRoomOrdersToCashByUserId(param *request.OrdersCashReq) *dingo.ErrorWrap {
	dbData := &request.OrdersCashRes{}

	t, _ := time.ParseDuration("-48h")
	minTime := "'" + time.Now().Add(t).Format("2006-01-02 15:04:05") + "'"
	fields := fmt.Sprintf(`SUM(IF(pay_time<=%s,amount,0))cash,SUM(IF(pay_time>%s,amount,0))not_cash`, minTime, minTime)
	db := global.Orm.Table("room_orders").Select(fields)
	db.Where("status=? AND third_trade_no<>'' AND user_id=?", helper.TypeNumRoomOrderStatusDone, param.UserId)

	db.Find(&dbData)
	return dingo.ErrorIf(db.Error, dbData)
}

// 更新支付金额
func (dao *RoomDao) UpdateRoomOrdersAmount(tradeNo string, amount int) error {
	updateData := map[string]interface{}{"amount": amount}
	db := global.Orm.Table("room_orders").Where("trade_no=?", tradeNo).Updates(updateData)
	return db.Error
}

// 设置订单状态
func (dao *RoomDao) SetH5RoomOrdersStatus(OrderInfo *room.Order, param *request.StewardSetDataReq) *dingo.ErrorWrap {
	if OrderInfo.Id <= 0 {
		return dingo.ErrorIf(nil, OrderInfo)
	}

	db := global.Orm.Table("room_orders").Where("trade_no=?", param.RoomTradeNo).Update("status", param.RoomOrderStatus)
	global.Orm.Table("places_service_notification").Where("id=?", OrderInfo.NotificationId).Updates(map[string]interface{}{
		"status":          helper.TypeNumNotificationStatusFinish,
		"user_id":         param.LoginUserId,
		"service_message": param.ServiceMessage,
	})

	return dingo.ErrorIf(db.Error, OrderInfo)
}

// 设置订单状态
func (dao *RoomDao) SetAdminRoomOrdersStatus(OrderInfo *room.Order, param *request.SetRoomOrderStatusReq) *dingo.ErrorWrap {
	if OrderInfo.Id <= 0 {
		return dingo.ErrorIf(nil, OrderInfo)
	}

	db := global.Orm.Table("room_orders").Where("trade_no=?", param.TradeNo)

	//if param.IsAdmin != helper.TypeNumIsAdminOperator {
	//	db.Where("user_id=?", param.LoginUserId)
	//}
	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("user_id=?", param.LoginUserId)
	}

	db.Update("status", param.Status)

	updateData := map[string]interface{}{
		"status": helper.TypeNumNotificationStatusFinish,
	}
	if param.RejectMessage != "" {
		updateData["service_message"] = param.RejectMessage
	}
	global.Orm.Table("places_service_notification").Where("id=?", param.NotificationId).Updates(updateData)

	return dingo.ErrorIf(db.Error, OrderInfo)
}

// GetAdminRoomOrdersByNotificationIds 查询房间订单
func (dao *RoomDao) GetAdminRoomOrdersByNotificationIds(notificationIds []int) *dingo.ErrorWrap {
	var lst []*room.Order
	db := global.Orm.Table("room_orders").Where("notification_id in ?", notificationIds)

	db.Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 查询房间订单
func (dao *RoomDao) GetH5RoomOrdersInfo(param *request.StewardSetDataReq) *dingo.ErrorWrap {
	OrderInfo := &room.Order{}

	db := global.Orm.Table("room_orders ro").Select("ro.*")
	db.Joins("LEFT JOIN places_staff ps ON ro.place_id=ps.place_id")
	db.Where("trade_no=?", param.RoomTradeNo).Where("ps.staff_id=?", param.LoginUserId)

	db.Find(&OrderInfo)
	return dingo.ErrorIf(db.Error, OrderInfo)
}

// 查询房间订单
func (dao *RoomDao) GetAdminRoomOrdersInfo(param *request.SetRoomOrderStatusReq) *dingo.ErrorWrap {
	OrderInfo := &room.Order{}

	db := global.Orm.Table("room_orders").Where("trade_no=?", param.TradeNo)

	//if param.IsAdmin != helper.TypeNumIsAdminOperator {
	//	db.Where("user_id=?", param.LoginUserId)
	//}
	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("user_id=?", param.LoginUserId)
	}

	db.Find(&OrderInfo)
	return dingo.ErrorIf(db.Error, OrderInfo)
}

// 更新房间状态
func (dao *RoomDao) UpdateRoomStatus(params *room.Room) *dingo.ErrorWrap {
	db := global.Orm.Model(&params).Where("id=?", params.Id).Update("status", params.Status)
	return dingo.ErrorIf(db.Error)
}

// 更新房间订单状态
func (dao *RoomDao) UpdateRoomOrder(params *room.OrderDb) *dingo.ErrorWrap {
	updateData := map[string]interface{}{
		"status": params.Status,
	}
	if params.ThirdTradeNo != "" {
		updateData["third_trade_no"] = params.ThirdTradeNo
	}
	if params.NotificationId > 0 {
		updateData["notification_id"] = params.NotificationId
	}
	if params.Status == helper.TypeNumRoomOrderStatusDoneWait {
		updateData["pay_time"] = time.Now().Format("2006-01-02 15:04:05")
	}

	db := global.Orm.Model(&room.Order{}).Where("trade_no=?", params.TradeNo).Updates(updateData)
	return dingo.ErrorIf(db.Error)
}

func (dao *RoomDao) GetRoomOrderPlace(tradeNo string) *room.OrderResult {
	dataInfo := &room.OrderResult{}

	fields := `ro.member_id,ro.place_id,ro.device_sn,p.place_name,r.room,DATE_FORMAT
	(ro.in_time,'%Y-%m-%d %T')in_time,DATE_FORMAT(ro.leave_time,'%Y-%m-%d %T')leave_time`
	db := global.Orm.Table("room_orders ro").Select(fields)
	db.Joins("LEFT JOIN places p ON ro.place_id=p.id")
	db.Joins("LEFT JOIN room r on ro.device_sn = r.device_sn AND r.id=ro.room_id")
	db.Where("ro.trade_no=?", tradeNo).Find(&dataInfo)

	phone := ""
	global.Orm.Table("members").Where("id=?", dataInfo.MemberId).Select("phone").Find(&phone)
	dataInfo.Phone = phone

	return dataInfo
}

// CreateRoomOrder 房间订单
func (dao *RoomDao) CreateRoomOrder(param *room.OrderDb) *dingo.ErrorWrap {
	if param.PlaceName == "" {
		placeInfo := &placemodel.PlaceModel{}
		global.Orm.Table("places").Where("id=?", param.PlaceId).Find(&placeInfo)
		param.PlaceName = placeInfo.PlaceName
	}

	if param.MemberPhone == "" {
		memberInfo := &membermodel.MembersModel{}
		global.Orm.Table("members").Where("id=?", param.MemberId).Find(&memberInfo)
		param.MemberPhone = memberInfo.Phone
		param.MemberName = memberInfo.NickName
	}

	db := global.Orm.Create(&param)
	return dingo.ErrorIf(db.Error, param)
}

// GetRoomOrderList 查询房间订单
func (dao *RoomDao) GetRoomOrderList(param *request.RoomOrderListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.RoomOrderListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `ro.id,member_id,ro.user_id,ro.place_id,room_id,ro.type_id,discounts_id,discounts_platform_amount,ro.discounts_amount, 
	price,amount,ro.status,pay_type,trade_no,ro.device_sn,ro.user_name,member_name,member_phone,message,p.place_name,DATE_FORMAT
	(pay_time,'%Y-%m-%d %k:%i')pay_time,DATE_FORMAT(in_time,'%Y-%m-%d %k:%i')in_time,DATE_FORMAT(in_time,'%Y-%m-%d %k:%i')in_time,
	DATE_FORMAT(ro.create_time,'%Y-%m-%d %k:%i')create_time,DATE_FORMAT(ro.update_time,'%Y-%m-%d %k:%i')update_time,r.room,ro.day_len`
	db := global.Orm.Table("room_orders ro").Select(fields)
	db.Joins("LEFT JOIN places p ON ro.place_id = p.id")
	db.Joins("LEFT JOIN room r on ro.device_sn = r.device_sn")

	if helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("ro.user_id=?", param.LoginUserId)
	}

	if param.TradeNo != "" {
		db.Where("ro.trade_no=?", param.TradeNo)
	}
	if param.Room != "" {
		db.Where("r.room=?", param.Room)
	}
	if param.PlaceId > 0 {
		db.Where("p.id=?", param.PlaceId)
	}
	if param.PayType > 0 {
		db.Where("ro.pay_type=?", param.PayType)
	}
	if param.Status > 0 {
		db.Where("ro.status=?", param.Status)
	}
	if param.PlaceName != "" {
		PlaceNameSql := fmt.Sprintf(`%s%s%s`, "%", param.PlaceName, "%")
		db.Where("p.place_name LIKE ? OR p.id LIKE ?", PlaceNameSql, PlaceNameSql)
	}
	if param.MemberPhone != "" {
		db.Where("ro.member_phone=?", param.MemberPhone)
	}

	db.Order("ro.id DESC")
	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)

	return dingo.ErrorIf(db.Error, lst, count)
}

// GetRoomDetails 查询房间配置详情
func (d *RoomDao) GetRoomDetails(placeId int, roomName string) *dingo.ErrorWrap {
	roomData := &room.Room{}
	if db := global.Orm.Where("place_id=? AND room=?", placeId, roomName).Find(&roomData); db.Error != nil {
		return dingo.ErrorIf(db.Error, roomData)
	}
	return dingo.ErrorIf(nil, roomData)
}

// SetRoomConfig 房间设置 新增/修改
func (d *RoomDao) SetRoomConfig(param *room.Db) *dingo.ErrorWrap {
	roomData := &room.Room{}
	if db := global.Orm.Where("place_id=? AND room=?", param.PlaceId, param.Room).Find(&roomData); db.Error != nil {
		return dingo.ErrorIf(db.Error)
	}

	if roomData.Id > 0 {
		param.Sort = roomData.Sort
		param.Level = roomData.Level
		db := global.Orm.Where("id=?", roomData.Id).Updates(&param)
		if param.TypeId == 0 {
			db.Update("type_id", 0)
		}
		if param.WifiPassword == "" {
			db.Update("wifi_password", "")
		}
		return dingo.ErrorIf(db.Error)
	}

	db := global.Orm.Create(&param)
	return dingo.ErrorIf(db.Error)
}

// GetWxRoomTypeInfo 查询当前设备房间类型
func (dao *RoomDao) GetWxRoomTypeInfo(param *request.GetRoomTypeListReq) *dingo.ErrorWrap {
	dataInfo := &request.GetRoomTypeListRes{}

	sql := `SELECT * FROM (SELECT type_id,id room_id,COUNT(1)num FROM room WHERE device_sn=? AND 
	place_id=? AND room=? GROUP BY type_id) r LEFT JOIN room_type rt ON rt.id=r.type_id`
	db := global.Orm.Raw(sql, param.DeviceSn, param.PlaceId, param.Room).Find(&dataInfo)

	return dingo.ErrorIf(db.Error, dataInfo)
}

// GetWxRoomOrderDetails 查询房间订单详情
func (dao *RoomDao) GetWxRoomOrderDetails(param *request.GetRoomOrderDetailsReq) *dingo.ErrorWrap {
	var lst []*room.OrderDb

	db := global.Orm.Table("room_orders ro").Select("ro.*")
	db.Joins("LEFT JOIN places_service_notification psn ON ro.notification_id=psn.id")
	db.Where("psn.id=? AND ro.member_id=?", param.NotificationId, param.MemberId)

	return dingo.ErrorIf(db.Error, lst)
}

// GetWxRoomTypeList 查询房间类型
func (dao *RoomDao) GetWxRoomTypeList(param *request.GetRoomTypeListReq) *dingo.ErrorWrap {
	var lst []*request.GetRoomTypeListRes

	sql := `SELECT * FROM (SELECT type_id,COUNT(1)num FROM room WHERE status=1 OR 
	device_sn=? AND place_id=? GROUP BY type_id) r LEFT JOIN room_type rt ON rt.id=r.type_id`
	db := global.Orm.Raw(sql, param.DeviceSn, param.PlaceId).Find(&lst)

	return dingo.ErrorIf(db.Error, lst)
}

// GetRoomTypeList 查询房间类型
func (dao *RoomDao) GetRoomTypeList(param *request.RoomTypeListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.RoomTypeListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `rt.id,place_id,price,discounts_amount,in_people_num,window_type,rt.status,min_area,max_area,
	type_name,icon,img_list,service,equipment,DATE_FORMAT(create_time,'%Y-%m-%d %k:%i')create_time,
	DATE_FORMAT(update_time,'%Y-%m-%d %k:%i')update_time,p.place_name`
	db := global.Orm.Table("room_type rt").Select(fields)
	db.Joins("LEFT JOIN places p ON rt.place_id = p.id")

	if param.IsAdmin != helper.TypeNumIsAdminOperator {
		//db.Where("p.user_id=?", param.LoginUserId)
		uList := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int)
		pList := NewUserDao().GetPlacesIds(param.LoginUserId, uList).Unwrap().([]int)
		db.Where("p.id IN ?", pList)
	}

	if param.PlaceId > 0 {
		db.Where("p.id=?", param.PlaceId)
	}
	if param.TypeName != "" {
		typeNameSql := fmt.Sprintf(`%s%s%s`, "%", param.TypeName, "%")
		db.Where("rt.type_name LIKE ? OR rt.id LIKE ?", typeNameSql, typeNameSql)
	}
	if param.Status > 0 {
		db.Where("rt.status=?", param.Status)
	}
	if param.PlaceName != "" {
		PlaceNameSql := fmt.Sprintf(`%s%s%s`, "%", param.PlaceName, "%")
		db.Where("p.place_name LIKE ? OR p.id LIKE ?", PlaceNameSql, PlaceNameSql)
	}

	db.Order("rt.id DESC")
	db.Limit(limit).Offset(offset).Find(&lst)

	if param.NotPagingStatus == 0 {
		db.Limit(-1).Offset(-1).Count(&count)
	}
	return dingo.ErrorIf(db.Error, lst, count)
}

func (dao *RoomDao) GetRoomTypeDetails(typeId int) *dingo.ErrorWrap {
	dbData := &request.RoomTypeListRes{}
	db := global.Orm.Table("room_type rt").Where("rt.id=?", typeId).Select("rt.*,p.user_id,p.user_name,p.place_name")
	db.Joins("LEFT JOIN places p ON rt.place_id = p.id")
	db.Find(&dbData)
	return dingo.ErrorIf(db.Error, dbData)
}

func (dao *RoomDao) InsertRoomType(param *room.TypeDb) *dingo.ErrorWrap {
	db := global.Orm.Create(&param)
	return dingo.ErrorIf(db.Error)
}

func (dao *RoomDao) UpdateRoomType(param *room.TypeDb) *dingo.ErrorWrap {
	db := global.Orm.Where("id=?", param.Id).Updates(&param)
	return dingo.ErrorIf(db.Error)
}

func (dao *RoomDao) DeleteRoomType(param *room.TypeDb) *dingo.ErrorWrap {
	var num int64
	if global.Orm.Table("room").Where("type_id=?", param.Id).Count(&num); num > 0 {
		return dingo.ErrorIf(errors.New("已关联房间，暂不能删除"))
	}

	db := global.Orm.Model(&param).Delete("id=?", param.Id)
	return dingo.ErrorIf(db.Error)
}

func (d *RoomDao) DeletePlaceRoom(room string, placeId int) *dingo.ErrorWrap {
	db := global.Orm.Exec("delete from room where place_id = ? and room = ?", placeId, room)
	return dingo.ErrorIf(db.Error, true)
}

func (d *RoomDao) ClearPlaceRoom(placeId int) *dingo.ErrorWrap {
	db := global.Orm.Exec("delete from room where place_id = ?", placeId)
	return dingo.ErrorIf(db.Error, true)
}

// 修改房间号
func (d *RoomDao) UpdatePlaceRoom(param *request.SetStewardDeviceReq) *dingo.ErrorWrap {
	db := global.Orm.Table("room").Where("id = ?", param.Id).Updates(map[string]interface{}{
		"room":          param.Room,
		"wifi_name":     param.WifiName,
		"wifi_password": param.WifiPassword,
		"device_sn":     param.DeviceSn,
	})

	return dingo.ErrorIf(db.Error, true)
}

func (d *RoomDao) UpdateDeviceRoom(param *request.SetStewardDeviceReq) *dingo.ErrorWrap {
	db := global.Orm.Table("devices").Where("device_sn = ?", param.DeviceSn).Updates(map[string]interface{}{
		"room": param.Room,
	})

	return dingo.ErrorIf(db.Error, true)
}

// 判断设备号是否绑定
func (d *RoomDao) SearchRoomIsBindDeviceSn(param *request.SetStewardDeviceReq) *dingo.ErrorWrap {
	var total int64
	db := global.Orm.Table("room").Raw("select count(1) as total from room where device_sn = ? and id != ?", param.DeviceSn, param.Id).Find(&total)

	return dingo.ErrorIf(db.Error, total)
}

func (d *RoomDao) GetRoomDetailsByDeviceSn(deviceSn string) *dingo.ErrorWrap {
	roomData := &room.Room{}
	if db := global.Orm.Where("device_sn=?", deviceSn).Find(&roomData); db.Error != nil {
		return dingo.ErrorIf(db.Error, roomData)
	}
	return dingo.ErrorIf(nil, roomData)
}

func (d *RoomDao) GetRoomDetailsByWifiName(wifiName string) *dingo.ErrorWrap {
	roomData := &room.Room{}
	if db := global.Orm.Where("wifi_name = ?", wifiName).Find(&roomData); db.Error != nil {
		return dingo.ErrorIf(db.Error, roomData)
	}
	return dingo.ErrorIf(nil, roomData)
}

// 解绑wifi信息， wifi帐号密码留着，门店信息清空
func (d *RoomDao) UnbindWifiInfoByDeviceSn(id int, deviceSn string) *dingo.ErrorWrap {
	var sn = utils.Join(deviceSn, "-", strconv.Itoa(id), "-", time.Now().String())
	db := global.Orm.Exec("update room set place_id = 0,device_sn = ? where device_sn = ?", sn, deviceSn)
	if db.Error != nil {
		return dingo.ErrorIf(db.Error, false)
	}
	return dingo.ErrorIf(db.Error, true)
}
